﻿using System.Collections.Generic;

namespace ScrumBox.AcceptanceTests.HelloWorld
{
    internal class Customer
    {
        public bool approved;
        public string name;

        public Customer(string name)
        {
            this.name = name;
        }
    }

    internal class CustomerDatabase
    {
        private readonly Queue<Customer> creditChecks = new Queue<Customer>();
        private readonly List<Customer> customers = new List<Customer>();

        public int Register(Customer c)
        {
            var nextPos = customers.Count;
            customers.Add(c);
            creditChecks.Enqueue(c);
            return nextPos;
        }

        public bool IsCheckPending(int customerId)
        {
            return creditChecks.Contains(customers[customerId]);
        }

        public void Approve()
        {
            creditChecks.Dequeue().approved = true;
        }

        public Customer GetCustomer(int customerId)
        {
            return customers[customerId];
        }
    }

    public class RegistrationScript : fit.Fixture
    {
        /// <summary>
        /// name will be used with the "enter" command to update its value.
        /// </summary>
        public string name;

        /// <summary>
        /// Is used here to demonstrate how real software would be called by this test
        /// I.e. in a real world example this could check a database or use a mock etc.
        /// </summary>
        private readonly CustomerDatabase cd = new CustomerDatabase();
        private int customerId;

        /// <summary>
        /// Register will be called by the "press" command to execute it.
        /// </summary>
        public void Register()
        {
            customerId = cd.Register(new Customer(name));
        }

        /// <summary>
        /// IsCheckPending will be called by the "check" command which will read back its return value.
        /// </summary>
        /// <returns></returns>
        public bool IsCheckPending()
        {
            return cd.IsCheckPending(customerId);
        }

        /// <summary>
        /// IsApproved will be called by the "check" command which will read back its return value.
        /// </summary>
        /// <returns></returns>
        public bool IsApproved()
        {
            return cd.GetCustomer(customerId).approved;
        }

        /// <summary>
        /// GetStoredName will be called by the "check" command which will read back its return value.
        /// </summary>
        /// <returns></returns>
        public string GetStoredName()
        {
            return cd.GetCustomer(customerId).name;
        }

        /// <summary>
        /// Approve will be called by the "press" command to execute it.
        /// </summary>
        public void Approve()
        {
            cd.Approve();
        }
    }
}